package org.kepler.chat.api.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.kepler.chat.api.infra.AppConfig;
import org.kepler.chat.api.infra.filter.XssFilter;
import org.kepler.chat.api.infra.handler.CustomRestExceptionResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;

import javax.servlet.MultipartConfigElement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(WebMvcConfig.class);

    @Bean
    public FilterRegistrationBean characterEncodingFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        //注入过滤器
        registration.setFilter(characterEncodingFilter());
        //拦截规则
        registration.addUrlPatterns("/*");
        //过滤器名称
        registration.setName("CharacterEncodingFilter");
        //过滤器顺序
//    	registration.setOrder(1);
        return registration;
    }

    @Bean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        return characterEncodingFilter;
    }

    @Bean
    public FilterRegistrationBean xxsFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        //注入过滤器
        registration.setFilter(xssFilter());
        //拦截规则
        registration.addUrlPatterns("/*");
        //过滤器名称
        registration.setName("XssSqlFilter");
        //过滤器顺序
//    	registration.setOrder(1);
        return registration;
    }

    @Bean
    public XssFilter xssFilter() {
        XssFilter xssFilter = new XssFilter();
        return xssFilter;
    }

//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//    	// 多个拦截器组成一个拦截器链
//        // addPathPatterns 用于添加拦截规则
//        // excludePathPatterns 用户排除拦截
////        registry.addInterceptor(new SessionTimeOutInterceptor()).addPathPatterns("/**");
//        registry.addInterceptor(authenticationInterceptor()) .addPathPatterns("/**");
//        super.addInterceptors(registry);
//    }

//    @Bean
//    public AuthenticationInterceptor authenticationInterceptor() {
//        return new AuthenticationInterceptor();
//    }

//    /**
//     * 描述 : <注册视图处理器>. <br>
//     *<p>
//     <使用方法说明>
//     </p>
//     * @return
//     */
//    @Bean
//    public ViewResolver viewResolver() {
//        logger.info("ViewResolver");
//        FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver();
//        viewResolver.setPrefix("/templates");
//        viewResolver.setSuffix(".html");
//        viewResolver.setCache(true);
//        viewResolver.setRequestContextAttribute("request");
//        viewResolver.setAttributesMap(FreemarkerStaticModels.getInstance());
//        return viewResolver;
//    }

//    /**
//     * 描述 : <注册消息资源处理器>. <br>
//     *<p>
//     <使用方法说明>
//     </p>
//     * @return
//     */
//    @Bean
//    public MessageSource messageSource() {
//        logger.info("MessageSource");
//        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
//        messageSource.setBasename("config.messages.messages");
//
//        return messageSource;
//    }

    /**
     * 描述 : <注册servlet适配器>. <br>
     * <p>
     * <只需要在自定义的servlet上用@Controller("映射路径")标注即可>
     * </p>
     *
     * @return
     */
    @Bean
    public HandlerAdapter servletHandlerAdapter() {
        logger.info("HandlerAdapter");
        return new SimpleServletHandlerAdapter();
    }

    /**
     * 描述 : <资源访问处理器>. <br>
     * <p>
     * <可以在jsp中使用/static/**的方式访问/WEB-INF/static/下的内容>
     * </p>
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        logger.info("addResourceHandlers");
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }

    /**
     * 描述 : <文件上传处理器>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @return
     */
//    @Bean(name="multipartResolver")
//    public CommonsMultipartResolver commonsMultipartResolver(){
//        logger.info("CommonsMultipartResolver");
//        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
//        commonsMultipartResolver.setDefaultEncoding("utf-8");
//        commonsMultipartResolver.setMaxInMemorySize(40960);
//        commonsMultipartResolver.setMaxUploadSize(50485760000L);
//        return commonsMultipartResolver;
//    }
    @DependsOn(value = "appConfig")
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setLocation(AppConfig.getFile_repository_path());
        // 设置文件大小限制 ,超出设置页面会抛出异常信息，
        // 这样在文件上传的地方就需要进行异常信息的处理了;
        factory.setMaxFileSize("10MB"); // KB,MB
        /// 设置总上传数据总大小
        factory.setMaxRequestSize("50MB");
        // Sets the directory location where files will be stored.
        // factory.setLocation("路径地址");
        return factory.createMultipartConfig();
    }

    /**
     * 描述 : <异常处理器>. <br>
     * <p>
     * <系统运行时遇到指定的异常将会跳转到指定的页面>
     * </p>
     *
     * @return
     */
    @Bean(name = "exceptionResolver")
    public HandlerExceptionResolver simpleMappingExceptionResolver() {
        logger.info("CP_SimpleMappingExceptionResolver");
        CustomRestExceptionResolver exceptionResolver = new CustomRestExceptionResolver();
//        exceptionResolver.setDefaultErrorView("error/errorpage");
//        exceptionResolver.setExceptionAttribute("ex");
//        Properties properties = new Properties();
//        properties.setProperty("org.bigdata.frame.exception.BizException", "common/message");
//        properties.setProperty("java.lang.Throwable", "common/message");
//        exceptionResolver.setExceptionMappings(properties);
        return exceptionResolver;
    }

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        converter.setObjectMapper(objectMapper());
        return converter;
    }

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        return objectMapper;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new StringHttpMessageConverter());
        converters.add(mappingJackson2HttpMessageConverter());
        super.configureMessageConverters(converters);
    }

}